#include "core/main.h"

Bitmap Neighborhood::getBitmap(const SpriteCollection &spriteCollection) const {
    UINT maxHeight = 0;
    UINT maxWidth = 0;
    for (auto it = _data.begin(); it != _data.end(); ++it) {
        int id = *it;
        UINT width = Constants::NESTileSize;
        UINT height = Constants::NESTileSize;
        if (id >= 0) {
            const SpriteEntry &sprite = spriteCollection.GetSprite(id);
            width = sprite.bmp.Width();
            height = sprite.bmp.Height();
        }
        maxWidth = width > maxWidth ? width : maxWidth;
        maxHeight = height > maxHeight ? height : maxHeight;
    }

    // Add all bitmaps for the sprites in this neighborhood
    Bitmap bmp(maxWidth * _width, maxHeight * _height, RGBColor::Black);
    for (int y = 0; y < _height; y++) {
        for (int x = 0; x < _width; x++) {
            int id = _data[y * _width + x];
            if (id >= 0) {
                const SpriteEntry &sprite = spriteCollection.GetSprite(id);
                sprite.bmp.TransparentBltTo(bmp, x * maxWidth, y * maxHeight);
            }
        }
    }
    // bmp.FlipBlueAndRed();
    bmp.FlipVertical();
    return bmp;
}

void Neighborhood::saveFigure(const SpriteCollection &spriteCollection, const string &filename) const {
    getBitmap(spriteCollection).SavePNG(filename);
}

ostream & operator<< (ostream &os, const Neighborhood &neigh) {
    for (auto it = neigh.data().begin(); it != neigh.data().end(); ++it) {
        os << *it << " ";
    }
    return os;
}

OutputDataStream & operator<< (OutputDataStream &os, const Neighborhood &neigh) {
    os << neigh.width();
    os << neigh.height();
    os << neigh.data();
    return os;
}

InputDataStream & operator>> (InputDataStream &is, Neighborhood &neigh) {
    is >> neigh._width;
    is >> neigh._height;
    is >> neigh._data;
    return is;
}